using System;
using System.Text;

namespace Bbm.Persistence
{
	/// <summary>
	/// Provides a method to generate table names for object storage
	/// </summary>
	public interface INameFactory
	{
		/// <summary>
		///  Calculates a name for the given object storage 
		///  </summary><param name="key">
		///  The key type. May be null.
		///  </param><param name="value">
		///  The value value. Cannot be null.
		///  </param><param name="domain">
		///  The domain. May be null.
		///  </param><returns>
		///  A unique name which can be used for physical storage
		///  </returns>
		CacheStoreName GetNameForStore(Type key, Type value, string domain);
	}

    public class CacheStoreName
	{
		readonly string keyType;
		readonly string valueType;
		readonly string domain;

		public CacheStoreName(string keyType, string valueType, string domain)
		{
			if (keyType == null) 
				throw new ArgumentNullException("keyType");

			if (valueType == null) 
				throw new ArgumentNullException("valueType");

			if(valueType.Length == 0)
				throw new ArgumentOutOfRangeException("valueType", "Value Type cannot be empty.");

			if (domain == null) 
				throw new ArgumentNullException("domain");

			this.keyType = keyType;
			this.valueType = valueType;
			this.domain = domain;
		}

		public string KeyType
		{
			get { return keyType; }
		}

		public string ValueType
		{
			get { return valueType; }
		}

		public string Domain
		{
			get { return domain; }
		}

		public override string ToString()
		{
			var retval = new StringBuilder();

			if (keyType.Length != 0)
			{
				retval.Append(keyType);
				retval.Append('_');
			}

			retval.Append(valueType);

			if(domain.Length != 0)
			{
				retval.Append('_');
				retval.Append(domain);
			}

			return retval.ToString();
		}
	}
}